home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / eqstack < prev    next >
Encoding:
Text File  |  1988-04-08  |  5.6 KB  |  295 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *        eqstack.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "cmds.h"
  14. #include "heap.h"
  15. #include "eq.h"
  16. #include "token.h"
  17. #include "tokenstack.h"
  18. #include "tokenlists.h"
  19. #include "print.h"
  20. #include "error.h"
  21. #include "eqstack.h"
  22.  
  23. ptr        save_ptr = 0;
  24. mword    save_stack[SAVE_SIZE];
  25. ptr        max_save_stack = 0;
  26. qword    cur_level = LEVEL_ONE;
  27. group    cur_group = BOTTOM_LEVEL;
  28. ptr        cur_boundary = 0;
  29.  
  30. #define    check_full_save_stack() \
  31.     {if (save_ptr > max_save_stack) { \
  32.         max_save_stack = save_ptr; \
  33.         if (max_save_stack > SAVE_SIZE - 6) \
  34.             overflow("save size", SAVE_SIZE);}}
  35.  
  36. new_save_level (c)
  37.     group    c;
  38. {
  39.     check_full_save_stack();
  40.     save_type(save_ptr) = LEVEL_BOUNDARY;
  41.     save_level(save_ptr) = cur_group;
  42.     save_index(save_ptr) = cur_boundary;
  43.     if (cur_level == MAX_QUARTERWORD)
  44.         overflow("grouping levels", MAX_QUARTERWORD - MIN_QUARTERWORD);
  45.     cur_boundary = save_ptr;
  46.     cur_group = c;
  47.     incr(cur_level);
  48.     incr(save_ptr);
  49. }
  50.  
  51. eq_destroy (w)
  52.     mword    w;
  53. {
  54.     ptr        q;
  55.  
  56.     switch (eq_type_field(w))
  57.     {
  58.     case CALL:
  59.     case LONG_CALL:
  60.     case LONG_OUTER_CALL:
  61.         delete_token_ref(equiv_field(w));
  62.         break;
  63.  
  64.     case GLUE_REF:
  65.         delete_glue_ref(equiv_field(w));
  66.         break;
  67.  
  68.     case SHAPE_REF:
  69.         q = equiv_field(w);
  70.         if (q != NULL)
  71.             free_node(q, link(q) + link(q) + 1);
  72.         break;
  73.  
  74.     case BOX_REF:
  75.         flush_node_list(equiv_field(w));
  76.         break;
  77.     }
  78. }
  79.  
  80. eq_save (p, l)
  81.     ptr        p;
  82.     qword    l;
  83. {
  84.     check_full_save_stack();
  85.     if (l == LEVEL_ZERO)
  86.         save_type(save_ptr) = RESTORE_ZERO;
  87.     else {
  88.         save_stack[save_ptr] = eqtb[p];
  89.         incr(save_ptr);
  90.         save_type(save_ptr)= RESTORE_OLD_VALUE;
  91.     }
  92.     save_index(save_ptr) = p;
  93.     save_level(save_ptr) = l;
  94.     incr(save_ptr);
  95. }
  96.  
  97. eq_define (p, t, e)
  98.     ptr        p;
  99.     qword    t;
  100.     hword    e;
  101. {
  102.     if (eq_level(p) == cur_level)
  103.         eq_destroy(eqtb[p]);
  104.     else if (cur_level > LEVEL_ONE)
  105.         eq_save(p, eq_level(p));
  106.     eq_level(p) = cur_level;
  107.     eq_type(p) = t;
  108.     equiv(p) = e;
  109. }
  110.  
  111. eq_word_define (p, w)
  112.     ptr        p;
  113.     val        w;
  114. {
  115.     if (xeq_level[p - INT_BASE] != cur_level) {
  116.         eq_save(p, xeq_level[p - INT_BASE]);
  117.         xeq_level[p - INT_BASE] = cur_level;
  118.     }
  119.     eqtb[p].i = w;
  120. }
  121.  
  122. geq_define (p, t, e)
  123.     ptr        p;
  124.     qword    t;
  125.     hword    e;
  126. {
  127.     eq_destroy(eqtb[p]);
  128.     eq_level(p) = LEVEL_ONE;
  129.     eq_type(p) = t;
  130.     equiv(p) = e;
  131. }
  132.  
  133. geq_word_define (p, w)
  134.     ptr        p;
  135.     val        w;
  136. {
  137.     eqtb[p].i = w;
  138.     xeq_level[p - INT_BASE] = LEVEL_ONE;
  139. }
  140.  
  141. save_for_after (t)
  142.     hword    t;
  143. {
  144.     check_full_save_stack();
  145.     save_type(save_ptr) = INSERT_TOKEN;
  146.     save_level(save_ptr) = LEVEL_ZERO;
  147.     save_index(save_ptr) = t;
  148.     incr(save_ptr);
  149. }
  150.  
  151. unsave ()
  152. {
  153.     qword    l;
  154.     ptr        p;
  155.     hword    t;
  156.  
  157.     if (cur_level > LEVEL_ONE) {
  158.         decr(cur_level);
  159.         loop {
  160.             decr(save_ptr);
  161.             if (save_type(save_ptr) == LEVEL_BOUNDARY)    
  162.                 break;
  163.             p = save_index(save_ptr);
  164.             if (save_type(save_ptr) == INSERT_TOKEN) {
  165.                 t = cur_tok;
  166.                 cur_tok = p;
  167.                 back_input();
  168.                 cur_tok = t;
  169.             } else {
  170.                 if (save_type(save_ptr) == RESTORE_OLD_VALUE) {
  171.                     l = save_level(save_ptr);
  172.                     decr(save_ptr);
  173.                 } else 
  174.                     save_stack[save_ptr] = eqtb[UNDEFINED_CONTROL_SEQUENCE];
  175. #ifdef STAT
  176.                 if (p < INT_BASE) {
  177.                     if (eq_level(p) == LEVEL_ONE) {
  178.                         eq_destroy(save_stack[save_ptr]);
  179.                         if (tracing_restores > 0)
  180.                             restore_trace(p, "retaining");
  181.                     } else {
  182.                         eq_destroy(eqtb[p]);
  183.                         eqtb[p] = save_stack[save_ptr];
  184.                         if (tracing_restores > 0)
  185.                             restore_trace(p, "restoring");
  186.                     }
  187.                 } else if (xeq_level[p - INT_BASE] != LEVEL_ONE) {
  188.                     eqtb[p] = save_stack[save_ptr];
  189.                     xeq_level[p - INT_BASE] = l;
  190.                     if (tracing_restores > 0)
  191.                         restore_trace(p, "restoring");
  192.                 } else {
  193.                     if (tracing_restores > 0)
  194.                         restore_trace(p, "retaining");
  195.                 }
  196. #else
  197.                 if (p < INT_BASE) {
  198.                     if (eq_level(p) == LEVEL_ONE)
  199.                         eq_destroy(save_stack[save_ptr]);
  200.                     else {
  201.                         eq_destroy(eqtb[p]);
  202.                         eqtb[p] = save_stack[save_ptr];
  203.                     }
  204.                 } else if (xeq_level[p - INT_BASE] != LEVEL_ONE) {
  205.                     eqtb[p] = save_stack[save_ptr];
  206.                     xeq_level[p - INT_BASE] = l;
  207.                 }
  208. #endif
  209.             }
  210.         }
  211.         cur_group = save_level(save_ptr);
  212.         cur_boundary = save_index(save_ptr);
  213.     } else
  214.         confusion("curlevel");
  215. }
  216.  
  217. off_save ()
  218. {    
  219.     ptr        p;
  220.  
  221.     if (cur_group == BOTTOM_LEVEL) {
  222.         print_err("Extra ");
  223.         print_cmd_chr(cur_cmd, cur_chr);
  224.         help_offsave_xtra();
  225.         error();
  226.     } else {
  227.         back_input();
  228.         p = new_token();
  229.         token_link(temp_toks) = p;
  230.         print_err("Missing ");
  231.         switch (cur_group) 
  232.         {
  233.         case SEMI_SIMPLE_GROUP:
  234.             token(p) = CS_TOKEN_FLAG + FROZEN_END_GROUP;
  235.             print_esc("groupend");
  236.             break;
  237.         
  238.         case MATH_SHIFT_GROUP:
  239.             token(p) = MATH_SHIFT_TOKEN + '$';
  240.             print_char('$');
  241.             break;
  242.         
  243.         case MATH_LEFT_GROUP:
  244.             token(p) = CS_TOKEN_FLAG + FROZEN_RIGHT;
  245.             token_link(p) = new_token();
  246.             p = token_link(p);
  247.             token(p) = OTHER_TOKEN + '.';
  248.             print_esc("right.");
  249.             break;
  250.         
  251.         default:
  252.             token(p) = RIGHT_BRACE_TOKEN + '}';
  253.             print_char('}');
  254.             break;
  255.         }
  256.         print(" inserted");
  257.         ins_list(token_link(temp_toks));
  258.         help_offsave_missing();
  259.         error();
  260.     }
  261. }
  262.  
  263. #ifdef STAT
  264. restore_trace (p, s)
  265.     ptr        p;
  266.     char*    s;
  267. {
  268.     begin_diagnostic();
  269.     print_char('{');
  270.     print(s);
  271.     print_char(' ');
  272.     show_eqtb(p);
  273.     print_char('}');
  274.     end_diagnostic(FALSE);
  275. }
  276. #endif
  277.  
  278. /*
  279.  *    Help text
  280.  */
  281.  
  282. help_offsave_xtra ()
  283. {    
  284.     help1("Things are pretty mixed up, but I think the worst is over.");
  285. }
  286.  
  287. help_offsave_missing ()
  288. {
  289.     help5("I've inserted something that you may have forgotten.",
  290.     "(see the <inserted text> above.)",
  291.     "With luck, this will get me unwedged. But if you",
  292.     "really didn't forget anything, try typing `2' now; then",
  293.     "my insertion and my current dilemma will both disappear.");
  294. }
  295.